package com.fzu.messageservice.websocket;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.fzu.commonutil.entity.ImChatUserMessage;
import com.fzu.commonutil.entity.User;
import com.fzu.commonutil.util.CommonConst;
import com.fzu.commonutil.util.JwtUtil;
import com.fzu.messageservice.client.NormalClient;
import com.fzu.messageservice.service.ImChatUserMessageService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.tio.core.ChannelContext;
import org.tio.core.Tio;
import org.tio.http.common.HttpRequest;
import org.tio.http.common.HttpResponse;
import org.tio.utils.lock.SetWithLock;
import org.tio.websocket.common.WsRequest;
import org.tio.websocket.common.WsResponse;
import org.tio.websocket.server.handler.IWsMsgHandler;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Component
@Slf4j
public class ImWsMsgHandler implements IWsMsgHandler {

//    @Autowired
//    private ImChatGroupUserService imChatGroupUserService;

    @Autowired
    private ImChatUserMessageService imChatUserMessageService;

    @Autowired
    private NormalClient normalClient;

    @Autowired
    private MessageCache messageCache;

//    @Autowired
//    private CommonQuery commonQuery;

    /**
     * 握手时走这个方法，业务可以在这里获取cookie，request等
     * 对httpResponse参数进行补充并返回，如果返回null表示不想和对方建立连接
     * 对于大部分业务，该方法只需要一行代码：return httpResponse;
     */
    @Override
    public HttpResponse handshake(HttpRequest httpRequest, HttpResponse httpResponse, ChannelContext channelContext) {
        String token = httpRequest.getParam(CommonConst.TOKEN);
        log.info("尝试握手");
        log.info("token:{}",token);
        if (!StringUtils.hasText(token)) {
            return null;
        }
        User user = JwtUtil.getUser(token);
        if (user == null) {
            return null;
        }

        log.info("握手成功：用户ID：{}, 用户名：{}", user.getId(), user.getNickName());

        return httpResponse;
    }

    /**
     * 握手成功后触发该方法
     */
    @Override
    public void onAfterHandshaked(HttpRequest httpRequest, HttpResponse httpResponse, ChannelContext channelContext) {
        //获取token，用户信息
        String token = httpRequest.getParam(CommonConst.TOKEN);
        User user = JwtUtil.getUser(token);
        //关闭某用户的所有连接
        Tio.closeUser(channelContext.tioConfig, user.getId().toString(), null);
        //绑定用户
        Tio.bindUser(channelContext, user.getId().toString());
        //获取发送给当前用户的信息
        LambdaQueryWrapper<ImChatUserMessage> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(ImChatUserMessage::getToId, user.getId());
        lambdaQueryWrapper.eq(ImChatUserMessage::getMessageStatus, ImConfigConst.USER_MESSAGE_STATUS_FALSE);
        lambdaQueryWrapper.orderByAsc(ImChatUserMessage::getCreateTime);
        List<ImChatUserMessage> userMessages = imChatUserMessageService.list(lambdaQueryWrapper);
        //如果发送给当前用户的信息不为空，则遍历消息，将消息转化为ImMessage
        if (!CollectionUtils.isEmpty(userMessages)) {
            List<Long> ids = new ArrayList<>();
            userMessages.forEach(userMessage -> {
                ids.add(userMessage.getId());
                ImMessage imMessage = new ImMessage();
                imMessage.setContent(userMessage.getContent());
                imMessage.setFromId(userMessage.getFromId());
                imMessage.setToId(userMessage.getToId());
                imMessage.setMessageType(ImEnum.MESSAGE_TYPE_MSG_SINGLE.getCode());
                WsResponse wsResponse = WsResponse.fromText(JSON.toJSONString(imMessage), ImConfigConst.CHARSET);
                //发消息给指定用户
                Tio.sendToUser(channelContext.tioConfig, userMessage.getToId().toString(), wsResponse);
                userMessage.setMessageStatus(ImConfigConst.USER_MESSAGE_STATUS_TRUE);
            });
            imChatUserMessageService.updateBatchById(userMessages);
        }
    }

    @Override
    public Object onBytes(WsRequest wsRequest, byte[] bytes, ChannelContext channelContext) {
        return null;
    }

    @Override
    public Object onClose(WsRequest wsRequest, byte[] bytes, ChannelContext channelContext) {
        Tio.remove(channelContext, "连接关闭");
        return null;
    }

    @Override
    public Object onText(WsRequest wsRequest, String text, ChannelContext channelContext) {
        log.info("onText()方法");
        if (!StringUtils.hasText(text)) {
            return null;
        }
        log.info("text:{}",text);
        try {
            ImMessage imMessage = JSON.parseObject(text, ImMessage.class);
            log.info("ImMessage:{}",imMessage);
            WsResponse wsResponse = WsResponse.fromText(text, ImConfigConst.CHARSET);
            if (imMessage.getMessageType().intValue() == ImEnum.MESSAGE_TYPE_MSG_SINGLE.getCode()) {
                //单聊
                ImChatUserMessage userMessage = new ImChatUserMessage();
                userMessage.setFromId(imMessage.getFromId());
                userMessage.setToId(imMessage.getToId());
                userMessage.setContent(imMessage.getContent());
                userMessage.setCreateTime(new Date());

                SetWithLock<ChannelContext> setWithLock = Tio.getByUserid(channelContext.tioConfig, imMessage.getToId().toString());
                log.info("setWithLock:{}",setWithLock);
                if (setWithLock != null && setWithLock.size() > 0) {
                    Tio.sendToUser(channelContext.tioConfig, imMessage.getToId().toString(), wsResponse);
                    userMessage.setMessageStatus(ImConfigConst.USER_MESSAGE_STATUS_TRUE);
                } else {
                    userMessage.setMessageStatus(ImConfigConst.USER_MESSAGE_STATUS_FALSE);
                }
                messageCache.putUserMessage(userMessage);
                Tio.sendToUser(channelContext.tioConfig, imMessage.getFromId().toString(), wsResponse);
            }
        } catch (Exception e) {
            log.error("解析消息失败：{}", e.getMessage());
        }
        //返回值是要发送给客户端的内容，一般都是返回null
        return null;
    }
}
